#!/usr/bin/env bash

alias brewup='brew update; brew upgrade; brew cleanup; brew doctor'

# Shortcuts
alias G="cd ~/gitrepos"

alias ls="exa --git -lFha --group-directories-first --no-user"
alias lg=lazygit

# List only directories
alias lsd="exa -lhF --no-user | grep --color=never '^d'"

alias cat="bat --color=always"

alias nn="nnn"

alias ...="../../"
alias ....="../../../"
alias .....="../../../../"
alias ......="../../../../../"
alias .......="../../../../../../"
alias ........="../../../../../../../"
alias .........="../../../../../../../../"

alias mv='mv -iv'
alias cp='cp -iv'
alias mkdir='mkdir -pv'
alias tree="exa --tree"

# Get week number
alias week='date +%V'

# Stopwatch
# alias timer='echo "Timer started. Stop with Ctrl-D." && date && time cat && date'

# Flush Directory Service cache
# alias flush="dscacheutil -flushcache && killall -HUP mDNSResponder"

# Clean up LaunchServices to remove duplicates in the “Open With” menu
# alias lscleanup="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user && killall Finder"

# View HTTP traffic
# alias sniff="sudo ngrep -d 'en1' -t '^(GET|POST) ' 'tcp and port 80'"
# alias httpdump="sudo tcpdump -i en1 -n -s 0 -w - | grep -a -o -E \"Host\: .*|GET \/.*\""

# Canonical hex dump; some systems have this symlinked
# command -v hd > /dev/null || alias hd="hexdump -C"

# OS X has no `md5sum`, so use `md5` as a fallback
# command -v md5sum > /dev/null || alias md5sum="md5"

# OS X has no `sha1sum`, so use `shasum` as a fallback
# command -v sha1sum > /dev/null || alias sha1sum="shasum"

# Recursively delete `.DS_Store` files
alias cleanup="find . -type f -name '*.DS_Store' -ls -delete"

# Empty the Trash on all mounted volumes and the main HDD
# Also, clear Apple’s System Logs to improve shell startup speed
# alias emptytrash="sudo rm -rfv /Volumes/*/.Trashes; sudo rm -rfv ~/.Trash; sudo rm -rfv /private/var/log/asl/*.asl"

# Show/hide hidden files in Finder
# alias show="defaults write com.apple.finder AppleShowAllFiles -bool true && killall Finder"
# alias hide="defaults write com.apple.finder AppleShowAllFiles -bool false && killall Finder"

# Hide/show all desktop icons (useful when presenting)
# alias showdesktop="defaults write com.apple.finder CreateDesktop -bool true && killall Finder"
# alias hidedesktop="defaults write com.apple.finder CreateDesktop -bool false && killall Finder"

# URL-encode strings
# alias urlencode='python -c "import sys, urllib as ul; print ul.quote_plus(sys.argv[1]);"'

# Merge PDF files
# Usage: `mergepdf -o output.pdf input{1,2,3}.pdf`
alias mergepdf='/System/Library/Automator/Combine\ PDF\ Pages.action/Contents/Resources/join.py'

# Disable Spotlight
# alias spotoff="sudo mdutil -a -i off"
# Enable Spotlight
# alias spoton="sudo mdutil -a -i on"

# PlistBuddy alias, because sometimes `defaults` just doesn’t cut it
# alias plistbuddy="/usr/libexec/PlistBuddy"

# Ring the terminal bell, and put a badge on Terminal.app’s Dock icon
# (useful when executing time-consuming commands)
alias badge="tput bel"

# Intuitive map function
# For example, to list all directories that contain a certain file:
# find . -name .gitattributes | map dirname
alias map="xargs -n1"

# One of @janmoesen’s ProTip™s
# for method in GET HEAD POST PUT DELETE TRACE OPTIONS; do
# alias "$method"="lwp-request -m '$method'"
# done

# Make Grunt print stack traces by default
# command -v grunt > /dev/null && alias grunt="grunt --stack"

# Kill all the tabs in Chrome to free up memory
# [C] explained: http://www.commandlinefu.com/commands/view/402/exclude-grep-from-your-grepped-output-of-ps-alias-included-in-description
# alias chromekill="ps ux | grep '[C]hrome Helper --type=renderer' | grep -v extension-process | tr -s ' ' | cut -d ' ' -f2 | xargs kill"

# Lock the screen (when going AFK)
alias afk="/System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend"

# Reload the shell (i.e. invoke as a login shell)
alias reload="exec $SHELL -l"

alias cdg='cd $(git root)'
alias cdv='cd ~/.config/nvim'
alias cdd='cd ~/gitrepos/dotfiles'
alias cdn='cd ~/gitrepos/notes'
alias cdr='cd ~/gitrepos'

# tmux aliases
alias ta='tmux attach'
alias tls='tmux ls'
alias tat='tmux attach -t'
alias tns='tmux new-session -s'

alias ovim="command vim"

if [ -n "$NVIM" ]; then
  alias e=nvr --remote
else
  alias e=nvim
fi
alias nv='e'
alias vim='e'
alias vi='e'

export RG_FLAGS="--color=always --heading --line-number --trim --no-messages --smart-case --hidden --max-columns-preview --max-columns=\$(tput cols) --glob='!.git' --glob='!.DS_Store'"
alias rg="rg $RG_FLAGS"
alias raa="rg $RG_FLAGS --no-ignore --stats --follow --text --search-zip -uuu"

gifify() {
  if [[ -n "$1" ]]; then
    if [[ $2 == '--good' ]]; then
      ffmpeg -i $1 -r 10 -vcodec png out-static-%05d.png
      time convert -verbose +dither -layers Optimize -resize 1200x1200\> out-static*.png GIF:- | gifsicle --colors 128 --delay=5 --loop --optimize=3 --multifile - >$1.gif
      rm out-static*.png
    else
      ffmpeg -i $1 -s 600x400 -pix_fmt rgb24 -r 10 -f gif - | gifsicle --optimize=3 --delay=3 >$1.gif
    fi
  else
    echo "proper usage: gifify <input_movie.mov>. You DO need to include extension."
  fi
}

datetime() {
  date +%Y-%m-%dT%H:%M:%S%z
}

function get_nextword_data() {
  echo "Takes a long time to download..."
  mkdir ~/local/dictionary
  curl -L https://github.com/high-moctane/nextword-data/archive/large.tar.gz | tar zx -C ~/local/dictionary/
}

# custom type
# - Adds the -a flag (show all matches, not just the first)
# - Pretty print paths
# - Show symlink targets.
# - If any line is an alias, highlight the first word, and include a nested
#   type call for that word.
function type() {
  local gray='\e[38;5;8m'
  local blue='\e[34m'
  local bold='\e[1m'
  local reset='\e[0m'

  output="$(command type -a "$@")"

  # if there is no output, return
  if [[ -z "$output" ]]; then
    return 1
  fi

  local regex_path='^[[:graph:]]+ is [[:graph:]]+$' # case "WORD is /some/path"
  local regex_alias='^[[:graph:]]+ is aliased to'   # case "WORD is aliased to"
  local regex_is='^[[:graph:]]+ is '                # case "WORD is ..."

  # For every output line
  while IFS= read -r line; do
    # If line has the form "WORD is /some/path", pretty print the path and add
    # symlink target, if any.
    if [[ "$line" =~ $regex_path ]]; then
      local word="${line%% is*}"
      local path="${line#* is }"
      local pretty_path="$(pretty_print_directory "$path")"
      local output_line="${bold}${word}${reset} is ${pretty_path}"

      # symlink stuff
      local symlink_path="$(realpath "$path")"
      if [[ "$symlink_path" != "$path" ]]; then
        local pretty_symlink_path="$(pretty_print_directory "$symlink_path")"
        output_line="${output_line} ${gray}->${reset} ${pretty_symlink_path}"
      fi

      printf '%b\n' "$output_line"

    # If line has the form "WORD is aliased to `ALIAS ...", highlight alias
    elif [[ "$line" =~ $regex_alias ]]; then
      # Note that forms can be either:
      # - "WORD is aliased to `ALIAS ...'" or
      # - "WORD is aliased to `ALIAS'"
      local word="${line%% is*}"
      local rest="${line#* is aliased to \`}"
      local alias="${rest%%[ \']*}"
      local rest="${rest#*${alias}}"

      local is_alias_different_command=false
      if [[ "$word" != "$alias" ]]; then
        is_alias_different_command=true
      fi

      # if the alias is different than the word, highligh as blue
      local alias_highlight=${bold}
      if [[ "$is_alias_different_command" = true ]]; then
        alias_highlight=${bold}${blue}
      fi

      printf '%b\n' "${bold}${word}${reset} is aliased to \`${alias_highlight}${alias}${reset}${rest}"

      # if the alias is different, recursively call 'type' on it. Indent two spaces.
      if [[ "$is_alias_different_command" = true ]]; then
        local alias_output="$(type "$alias" | sed 's/^/  /')"
        printf '%b\n' "$alias_output"
      fi

    # If a line has the form "WORD is ...", highlight word.
    # This is just the catch-all case.
    elif [[ "$line" =~ $regex_is ]]; then
      local word="${line%% is*}"
      local rest="${line#* is }"
      printf '%b\n' "${bold}${word}${reset} is ${rest}"
    else
      printf '%s\n' "$line"
    fi
  done <<<"$output"
}

gli() {

  # param validation
  if [[ ! $(git log -n 1 "$@" | head -n 1) ]]; then
    return
  fi

  # filter by file string
  local filter
  # param existed, git log for file if existed
  if [ -n "$@" ] && [ -f "$@" ]; then
    filter="-- $@"
  fi

  # git command
  local gitlog=(
    git log
    --graph --color=always
    --abbrev=7
    --format='%C(auto)%h %an %C(blue)%s %C(yellow)%cr'
    "$@"
  )

  # fzf command
  local fzf=(
    fzf
    --ansi --no-sort --reverse --tiebreak=index
    --preview "f() { set -- \$(echo -- \$@ | grep -o '[a-f0-9]\{7\}'); [ \$# -eq 0 ] || git show --color=always \$1 $filter; }; f {}"
    --bind "ctrl-q:abort,ctrl-m:execute:
                (grep -o '[a-f0-9]\{7\}' | head -1 |
                xargs -I % sh -c 'git show --color=always % $filter | less -R') << 'FZF-EOF'
                {}
                FZF-EOF"
    --preview-window=right:60%
  )

  # piping them
  $gitlog | $fzf
}

alias gfap="gfa --prune"
alias gsb='git status -sb'
alias gst='git status -s'

alias luamake=/Users/$USER/gitrepos/lua-language-server/3rd/luamake/luamake
